/**********************************************
 * 姓名：fanfutian
 * 时间：2023/11/9                             
 * 文件名：student.cpp  
 * 功能：实现学生类中的成员函数
 *********************************************/
#include "student.h"

/*
 * 默认构造
 */
Student::Student(){
    this->initVectorCom();
    this->initMapOrder();
}

/*
 * 有参构造---学号，姓名，密码
 */
Student::Student(int id,string name,string pwd){
    this->m_id = id;
    this->m_name = name;
    this->m_pwd = pwd;

    this->initVectorCom();
    this->initMapOrder();
}



/*
 * 初始化机房容器
 */
void Student::initVectorCom() {
    ifstream ifs;
    ifs.open(COMPUTER_FILE,ios::in);
    if(!ifs.is_open()){
        cout << "文件不存在！" << endl;
        return;
    }
    ComputerRoom cr;
    while(ifs >> cr.com_id && ifs >> cr.com_max_num){
        this->v_stu_com.push_back(cr);
    }
    ifs.close();
}


/*
 * 初始化预约容器
 */
void Student::initMapOrder() {
    ifstream ifs;
    ifs.open(ORDER_FILE,ios::in);
    if(!ifs.is_open()){
        cout << "文件不存在！" << endl;
        return;
    }
    Order od;
    while(ifs >> od.s_name && ifs >> od.s_id && ifs >> od.com_num && ifs >> od.week && ifs >> od.course && ifs >> od.state){
        // 创建一个小容器
        map<string,string> m;

        // 使用字符串查找进行字符分割
        this->strFindSub(m,od.s_name);
        this->strFindSub(m,od.s_id);
        this->strFindSub(m,od.com_num);
        this->strFindSub(m,od.week);
        this->strFindSub(m,od.course);
        this->strFindSub(m,od.state);
        // 将小的map容器放入大的map容器中
        this->m_stu_od.insert(make_pair(m_stu_od.size(),m));
    }
    ifs.close();
}


/*
 * 传入一个字符串进行指定条件分割
 */
void Student::strFindSub(map<string,string> &m,string& str){
    string key,value;
    int pos = str.find(':');
    // 判断是否结尾
    if(pos != -1){
        // substr参数1表示截取的起始位置，参数2表示截取的长度
        key = str.substr(0,pos);
        value = str.substr(pos+1,str.size()-pos-1);
        m.insert(make_pair(key,value));
    }
}


/*
 * 重写父类的抽象函数
 */
void Student::showMenu(){
    cout << "欢迎学生" << this->m_name << "登录！" << endl;
    while(true){
        int chose = 0;
        cout << "**************************" << endl;
        cout << "\t\t1、申请预约" << endl;
        cout << "\t\t2、查看自身预约" << endl;
        cout << "\t\t3、查看所有预约" << endl;
        cout << "\t\t4、取消预约" << endl;
        cout << "\t\t5、注销登录" << endl;
        cout << "*************************" << endl;
        cout << "请输入你的选择：";
        cin >> chose;
        switch(chose){
            case 1:
                this->applyOrder();
                break;
            case 2:
                this->showMyOrder();
                break;
            case 3:
                this->showAllOrder();
                break;
            case 4:
                this->cancelOrder();
                break;
            case 5:
                cout << "成功退出登录！" << endl;
                return;
            default:
                cout << "输入错误！！" << endl;
                break;
        }
    }
}

/*
 * 打印容器中的内容
 */
void printStuCom(ComputerRoom& v_c){
    cout << "机房编号：" << v_c.com_id << " 机房最大容量：" << v_c.com_max_num << endl;
}


/*
 * 申请预约
 */
void Student::applyOrder(){
    // 如果机房信息为空，就提示无法预约
    if(v_stu_com.empty()){
        cout << "没有机房信息，无法预约！！" << endl;
        return;
    }
    cout << "机房信息如下：" << endl;
    for_each(v_stu_com.begin(),v_stu_com.end(),printStuCom);
    cout << "请选择机房：";
    int computRoom;
    cin >> computRoom;
    while(true){
        if(computRoom >= 1 && computRoom <= v_stu_com.size()){
            break;
        }
        else{
            cout << "输入错误！" << endl;
            cout << "请重新输入：";
            cin >> computRoom;
        }
    }
    cout << "机房开放时间为：" << endl;
    cout << "1、周一  2、周二  3、周三  4、周四  5、周五  6、周六" << endl;
    int week;
    cout << "请选择序号：";
    cin >> week;
    while (true){
        if(week >= 1 && week <= 6){
            break;
        }else{
            cout << "输入错误！" << endl;
            cout << "请重新输入：";
            cin >> week;
        }
    }
    cout << "课程时间段：" << endl;
    cout << "1、1-2节  2、3-4节  3、5-6节  4、7-9节  5、9-10节  6、11-12节" << endl;
    int course;
    cout << "请选择序号：";
    cin >> course;
    while(true){
        if(course >= 1 && course <= 6){
            break;
        }else{
            cout << "输入错误！" << endl;
            cout << "请重新输入：";
            cin >> course;
        }
    }
    cout << "正在生成预约，请稍后查询！" << endl;
    // 将预约信息写入文件中
    writeOrderFile(computRoom,week,course);
    // 文件写入成功后，刷新容器内容
    m_stu_od.clear();           // 清空里面原有的记录，不然会有重复
    this->initMapOrder();
}

/*
 * 写入预约信息到文件
 */
void Student::writeOrderFile(int computerRoom,int week,int kj,int status){
    // 创建文件流
    ofstream ofs;
    // 打开文件以追加的方式写入文件
    ofs.open(ORDER_FILE,ios::app);
    ofs << "预约学生:" << this->m_name << "  " << "学号:" << this->m_id << "  " << "机房号:" << computerRoom << "  " << "星期:" << week << "  " << "课节:" << kj << "  "  << "状态:"  << status;
    ofs << '\n';
    ofs.close();
}


/*
 * 查看自身预约
 */
void Student::showMyOrder(){
    if(this->m_stu_od.empty()){
        cout << "预约内容为空！" << endl;
        return;
    }
    // 遍历容器查找与当前用户相同的预约记录
    cout << "自身预约记录如下：" << endl;
    int emp = 0;
    for(int i = 0; i < this->m_stu_od.size(); i++){
        // 如果找到相同就打印
        if(this->m_stu_od[i]["预约学生"] == this->m_name && atoi(this->m_stu_od[i]["学号"].c_str()) == this->m_id){
            cout << "预约学生:" << this->m_stu_od[i]["预约学生"] << "  " << "学号:" << this->m_stu_od[i]["学号"]  << "  " << "机房号:" << this->m_stu_od[i]["机房号"]  << "  "
            << "星期:" << this->m_stu_od[i]["星期"]  << "  " << "课节:" << this->m_stu_od[i]["课节"] << "  " ;
            string status = "状态:";
            if(this->m_stu_od[i]["状态"] == "1"){
                status += "审核中";
            }else if(this->m_stu_od[i]["状态"] == "2"){
                status += "预约成功";
            }else if(this->m_stu_od[i]["状态"] == "-1"){
                status += "预约失败";
            }else{
                status += "取消预约";
            }
            cout << status << endl;
            emp = 1;
        }
    }
    if(emp==0){
        cout << "没有预约信息！" << endl;
    }
}


/*
 * 查看所有预约
 */
void Student::showAllOrder(){
    if(this->m_stu_od.empty()){
        cout << "预约内容为空！" << endl;
        return;
    }
    // 遍历容器查找与当前用户相同的预约记录
    cout << "所有预约记录如下：" << endl;
    for(int i = 0; i < this->m_stu_od.size(); i++){
        cout << "预约学生:" << this->m_stu_od[i]["预约学生"] << "  " << "学号:" << this->m_stu_od[i]["学号"]  << "  " << "机房号:" << this->m_stu_od[i]["机房号"]  << "  "
             << "星期:" << this->m_stu_od[i]["星期"]  << "  " << "课节:" << this->m_stu_od[i]["课节"] << "  " ;
        string status = "状态:";
        if(this->m_stu_od[i]["状态"] == "1"){
            status += "审核中";
        }else if(this->m_stu_od[i]["状态"] == "2"){
            status += "预约成功";
        }else if(this->m_stu_od[i]["状态"] == "-1"){
            status += "预约失败";
        }else{
            status += "取消预约";
        }
        cout << status << endl;
    }
}


/*
 * 取消预约
 */
void Student::cancelOrder(){
    if(this->m_stu_od.empty()){
        cout << "数据为空！" << endl;
        return;
    }
    // 修改容器中的数据
    for(int i = 0; i < this->m_stu_od.size(); i++){
        // 如果找到相同就修改状态
        if(this->m_stu_od[i]["预约学生"] == this->m_name && atoi(this->m_stu_od[i]["学号"].c_str()) == this->m_id){
            this->m_stu_od[i]["状态"] = "0";
        }
    }
    updateFile();
    cout << "取消成功！" << endl;
}


/*
 * 更新文件数据
 */
void Student::updateFile(){
    ofstream ofs(ORDER_FILE,ios::out | ios::trunc);
    for(int i = 0; i < this->m_stu_od.size(); i++){
        ofs << "预约学生:" << this->m_stu_od[i]["预约学生"] << "  ";
        ofs << "学号:" << this->m_stu_od[i]["学号"] << "  ";
        ofs << "机房号:" << this->m_stu_od[i]["机房号"] << "  ";
        ofs << "星期:" << this->m_stu_od[i]["星期"] << "  ";
        ofs << "课节:" << this->m_stu_od[i]["课节"] << "  ";
        ofs << "状态:" << this->m_stu_od[i]["状态"] << "  ";
        ofs << '\n';
    }
    ofs.close();
}